home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / boot / avwm.lzh / avwm-0.4 / callbacks.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  3KB  |  158 lines

  1. /*
  2.     callbacks for message ports
  3.     5/2/93 Bernhard Fastenrath
  4. */
  5.  
  6. #include <dos.h>
  7. #include <signal.h>
  8. #include <dos/dos.h>
  9. #include <exec/types.h>
  10. #include <pragmas/exec_pragmas.h>
  11.  
  12. #include "callbacks.h"
  13.  
  14. static struct CbPort *find_cbport (struct MsgPort *port);
  15.  
  16. static struct MinList port_list = { NULL, NULL, NULL };
  17. static ULONG signals = SIGBREAKF_CTRL_C;
  18.  
  19. ULONG free_signals = 0;
  20. callback signal_callback = NULL;
  21.  
  22. void
  23. RemoveAllCallbacks ()
  24. {
  25.   struct Callback *cnode;
  26.   struct CbPort *pnode;
  27.  
  28.   if (!port_list.mlh_Head) return;
  29.  
  30.   while (pnode = RemTail (&port_list))
  31.   {
  32.     while (cnode = RemTail (&pnode -> callbacks))
  33.       free (cnode);
  34.  
  35.     free (pnode);
  36.   }
  37.   signals = SIGBREAKF_CTRL_C;
  38. }
  39.  
  40. void
  41. RemoveCallback (struct Callback *cb)
  42. {
  43.   struct CbPort *node;
  44.  
  45.   Remove (cb);
  46.   free (cb);
  47.  
  48.   if (EmptyMinList (&cb -> cbport -> callbacks)) {
  49.     Remove (cb -> cbport);
  50.     free (cb -> cbport);
  51.   }
  52.   signals = SIGBREAKF_CTRL_C | free_signals;
  53.   for (node = port_list.mlh_Head; node -> node.mln_Succ; node = node -> node.mln_Succ)
  54.     signals |= node -> sig;
  55. }
  56.  
  57. struct Callback *
  58. AddPortCallback (struct MsgPort *port, callback fun, ULONG class)
  59. {
  60.   struct Callback *new_cb;
  61.   struct CbPort *pn;
  62.  
  63.   if (!port_list.mlh_Head)
  64.     InitListHeader (&port_list);
  65.  
  66.   if (!(pn = find_cbport (port)))
  67.     return NULL;
  68.  
  69.   if (!(new_cb = Malloc (struct Callback)))
  70.     return NULL;
  71.  
  72.   new_cb -> class = class;
  73.   new_cb -> function = fun;
  74.   new_cb -> cbport = pn;
  75.  
  76.   AddHead (&pn -> callbacks, new_cb);
  77.  
  78.   return new_cb;
  79. }
  80.  
  81. void
  82. SetSignalCallback (ULONG signal_mask, callback fun)
  83. {
  84.   free_signals = signal_mask;
  85.   signals |= free_signals;  
  86.   signal_callback = fun;
  87. }
  88.  
  89. void
  90. AppMainLoop ()
  91. {
  92.   struct IntuiMessage *msg;
  93.   ULONG received = 0;
  94.   struct CbPort *pnode;
  95.   struct Callback *cnode;
  96.  
  97.   while (!(received & SIGBREAKF_CTRL_C))
  98.   {
  99.     received = Wait (signals);
  100.  
  101.     if (free_signals & received)
  102.       signal_callback (received);
  103.       
  104.     for (pnode = port_list.mlh_Head; pnode -> node.mln_Succ; pnode = pnode -> node.mln_Succ)
  105.     {
  106.       while (msg = GetMsg (pnode -> port))
  107.       {
  108.     for (cnode = pnode -> callbacks.mlh_Head; cnode -> node.mln_Succ; cnode = cnode -> node.mln_Succ)
  109.     {
  110.       /* cnode -> class has to be zero for non-IntuiMessages which
  111.          don't have a `class' field following the message struct!
  112.           */
  113.       if (!cnode -> class || msg -> Class == cnode -> class)
  114.         if (cnode -> function (msg, cnode)) {
  115.           msg = NULL;
  116.               break;
  117.             }
  118.     }
  119.     if (msg && msg -> ExecMessage.mn_ReplyPort != pnode -> port)
  120.       ReplyMsg (msg);
  121.       }
  122.     }
  123.   }
  124. #if 0
  125.   printf ("AppMainLoop: User Break detected.\n");
  126. #endif
  127. }
  128.  
  129. void
  130. InitListHeader (struct MinList *list)
  131. {
  132.   list -> mlh_Head = &list -> mlh_Tail;
  133.   list -> mlh_TailPred = &list -> mlh_Head;
  134.   list -> mlh_Tail = 0;
  135. }
  136.  
  137. static struct CbPort*
  138. find_cbport (struct MsgPort *port)
  139. {
  140.   struct CbPort *pn;
  141.  
  142.   for (pn = port_list.mlh_Head; pn -> node.mln_Succ; pn = pn -> node.mln_Succ)
  143.     if (pn -> port == port)
  144.       return pn;
  145.  
  146.   if (!(pn = Malloc (struct CbPort)))
  147.     return NULL;
  148.   
  149.   pn -> port = port;
  150.   signals |= pn -> sig = 1L << port -> mp_SigBit;
  151.  
  152.   InitListHeader (&pn -> callbacks);
  153.  
  154.   AddHead (&port_list, (struct MinNode *) pn);
  155.  
  156.   return pn;
  157. }
  158.